Lab 01 - wprowadzenie i Docker

Lab. 01 - Wprowadzenie i Docker

Docker logo

1. Wprowadzenie

O czym jest ten przedmiot?

Zajęcia laboratoryjne z Autonomicznych Robotów Mobilnych mają na celu przybliżyć Państwu sposoby radzenia sobie z wyzwaniami napotykanymi podczas pracy z robotami, które niekontrolowane przez człowieka muszą wykonywać pracę poruszając się w zmiennej przestrzeni. Metody, które będziemy analizować mogą być używane na szerokiej gamie robotów: od mobilnych platform magazynowych, poprzez drony ratunkowe, na autonomicznych samochodach kończąc.

Jak będzie wyglądała praca?

Podczas zajęć będziecie Państwo zapoznawać się z instrukcją, wykonywać przedstawione w niej zadania i ostatecznie na podstawie zdobytej w ten sposób wiedzy wykonywać zadania domowe (w formie quizu lub programu do napisania).

Co jakiś czas odbywać się będą tzw. “Laboratoria problemowe”, gdzie, po wspólnej dyskusji na wstępie, zostaniecie Państwo postawieni przed otwartym problemem i celem zajęć będzie opracowanie rozwiązania korzystając z własnej wiedzy, zasobów internetowych i współpracy z resztą grupy. Zadaniem domowym po takich zajęciach będzie przygotowanie raportu z tego co udało się wykonać i przedstawienia propozycji dalszych kroków. Za satysfakcjonujące postępy, po tych zajęciach będzie możliwe zdobycie dodatkowych punktów (wiecej o punktacji).

Plan zajęć

  1. Spotkanie organizacyjne + podstawy Dockera
  2. ROS2 Action
  3. Lokalizacja laserowa 2D: SLAM (Simultaneous Localization And Mapping), AMCL
  4. Architektury behawioralne
  5. Laboratoria problemowe 1
  6. SLAM 3D
  7. Wizyjny SLAM cz. 1
  8. Wizyjny SLAM cz. 2
  9. Filtr Kalmana
  10. Lokalizacja topologiczna
  11. Laboratoria problemowe 2
  12. Deep Q-learning cz. 1
  13. Deep Q-learning cz. 2
  14. Zaliczenie
  15. Zaliczenie poprawkowe

Zaliczenie

Ocena za laboratoria składać się będzie z dwóch części: - Realizacji zadań domowych (50% oceny) - Testu na platformie eKursy (50% oceny)

Całkowita liczba zdobytych punktów za obie części może być podniesiona o dodatkowe punkty zdobyte podczas laboratoriów problemowych.

FAQ

2. Docker

Celem dalszej części zajęć jest poznanie podstaw użycia dockera i pracy z kontenerami w Visual Studio Code.

Docker jest określany jako narzędzie, które pozwala umieścić program oraz jego zależności (biblioteki, pliki konfiguracyjne, lokalne bazy danych itp.) w lekkim, przenośnym, wirtualnym kontenerze, który można uruchomić na prawie każdym serwerze z systemem opartym o jądro Linux. Kontenery wraz z zawartością działają niezależnie od siebie i nie wiedzą o swoim istnieniu. Mogą się jednak ze sobą komunikować w ramach ściśle zdefiniowanych kanałów wymiany informacji. Dzięki uruchamianiu na jednym wspólnym systemie operacyjnym, konteneryzacja oprogramowania jest znacznie lżejszym (mniej zasobochłonnym) sposobem wirtualizacji niż pełna wirtualizacja lub parawirtualizacja za pomocą wirtualnych systemów operacyjnych.[źródło]

Prace należy rozpocząć od zainstalowania Dockera.

Instalacja w Ubuntu 22.04

Uwaga, w przypadku pracy na komputerze w laboratorium, instalacja nie jest konieczna. Można wtedy pominąć część instrukcji i przejść TUTAJ. Dobrze byłoby jednak przejść te kroki na swoim prywatnym komputerze, ponieważ praca z kontenerami będzie niezbędna podczas zadań domowych.

Przygotowanie Apt repository:

sudo apt update
sudo apt install ca-certificates curl gnupg
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update

Instalacja Dockera:

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Weryfikacja instalacji:

sudo docker run hello-world

Zarządzanie dockerem jako non-root user

Utworzenie grupy docker:

sudo groupadd docker

Dodanie aktualnego użytkownika do grupy docker:

sudo usermod -aG docker $USER

Aktualizacja po zmianach grup:

newgrp docker

Weryfikacja konfiguracji bez sudo:

docker run hello-world

Aplikacje okienkowe GUI

Podczas zajęć konieczne będzie uruchamianie aplikacji okienkowych, np. żeby podejrzeć obraz z kamery lub wyświetlić wizualizację odczytów sensorów. Z tego powodu jeżeli ktoś posiada kartę GPU Nvidii, niezbędne jest zainstalowanie pakietu NVIDIA Container Toolkit zgodnie z instrukcją. Konieczna jest również instalacja sterowników Nvidia do wersji >= 418.81.07 (można do tego użyć aplikacji Software & Updates -> Additional Drivers i wybrać odpowiedni sterownik).

Jeżeli komputer jest wyposażony w kartę Nvidia i sterowniki zostały zainstalowane poprawnie, to po wywołaniu polecenia

nvidia-smi

powinni Państwo otrzymać odpowiedź przypominającą tę: Terminal with nvidia-smi

Widzimy tutaj wersję sterownika (535.86.05), nazwę karty graficznej (NVIDIA GeForce RTX 3080 Ti) oraz aktualne obciążenie (3%).

Instalacja NVIDIA Container Toolkit

Konfiguracja repozytorium Apt:

curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
  && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
    sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
    sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list \
  && \
    sudo apt-get update

Instalacja paczki:

sudo apt-get install -y nvidia-container-toolkit

Konfiguracja Dockera:

sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

Praca z Dockerem

Podczas korzystania z Dockera, nieustannie napotyka się dwa pojęcia: obraz i kontener, czyli image i container. Niezwykle ważne jest, żebyśmy je od siebie rozróżniali. - obraz (image) - to wzór danego systemu. Służy wyłącznie do odczytu. Zawiera kod, biblioteki, narzędzia, zależności i inne pliki niezbędne do uruchomienia. Może zostać utworzony z kontenera korzystając z polecenia docker commit. - kontener (container) - powstaje na skutek uruchomienia obrazu. Jest to odizolowane miejsce, gdzie aplikacja może być uruchamiana bez wpływu na resztę systemu. Raz zatrzymany kontener nie uruchomi się ponownie automatycznie. Po zatrzymaniu konenera, wprowadzone w nim zmiany są zapisywane.

Docker a wirtualna maszyna

Proszę znaleźć w sieci informacje o tym, jak docker różni się od wirtualnej maszyny, jakie ma zalety, a jakie wady.

Pobieranie obrazu i tworzenie kontenera

Pracę z dockerem należy rozpocząć od pobrania obrazu ubuntu:

docker pull ubuntu

Następnie możliwe jest utworzenie kontenera:

docker run ubuntu:latest

Tworząc kontener w ten sposób pozornie nic się nie dzieje. Nie jest on uruchamiany ani nie jest pokazywany w terminalu. Żeby od razu po utworzeniu uruchomić kontener i się do niego podłączyć, należy wywołać polecenie:

docker run -it ubuntu:latest bash

W ten sposób terminal od razu łączy się z kontenerem i umożliwia dalszą pracę.

Opuścić kontener można poleceniem exit lub kombinacją klawiszy ctrl+d. Po wyjściu kontener zostanie zatrzymany, ale jego aktualny stan jest zapisywany.

Listę wszystkich utworzonych kontenerów można wyświetlić poleceniem:

docker container ls -a

gdzie pominięcie -a skutkuje wyświetleniem wyłącznie uruchomionych kontenerów.

Usuwanie zbędnych kontenerów

Proszę wyświetlić listę wszystkich kontenerów i usunąć te utworzone wcześniej w ramach zajęć, korzystając z polecenia:

docker container rm ...

gdzie w miejsce ... należy wstawić nazwy kontenerów do usunięcia (możliwe jest podanie kilku oddzielonych spacją).

Korzystanie ze skryptów do tworzenia kontenerów

Przygotowanie kontenera może być czasochłonne i łatwo pominąć istotne argumenty, dlatego dobrą praktyką jest przygotowywanie plików bash (.sh), które tworzą kontener.

W zależności od możliwości sprzętowych proszę, korzystając ze skryptów dla osób bez GPU oraz z GPU NVIDIA, należy utworzyć kontener poleceniem:

bash run_cpu.sh

lub

bash run_gpu_nvidia.sh

Po uruchomieniu skryptów terminal powinien być podłączony do kontenera o nazwie ARM_01.

UWAGA! Skrypty automatycznie usuwają kontener ARM_01 jeżeli taki już istnieje na danym komputerze.

Podstawowe operacje w dockerze

Zatrzymany kontener można uruchomić poleceniem

docker start ARM_01

Do kontenera można podłączyć się z wielu terminali poleceniem

docker exec -it ARM_01 bash

Kontener można zatrzymać poleceniem

docker stop ARM_01

Obraz można usunąć poleceniem:

docker image rm ubuntu

Autouzupełnianie w dockerze

Czasami autouzupełnianie z użyciem przycisku TAB nie jest domyślnie zainstalowane w pobranym obrazie. Pakiet można doinstalować poleceniem

apt install bash-completion

Jak widać, korzystając z dockera nie musimy użwyać polecenia sudo. Domyślnie jesteśmy zalogowani w kontenerze jako root.

Jednoczesna obsługa wielu terminali

W wielu praktycznych zastosowaniach robotyki konieczne jest korzystanie z obsługi wielu terminali jednocześnie. Możliwe jest oczywiście przełączanie się między wieloma instancjami terminala, ale wygodniejsze bywa korzystanie z takich alternatyw jak: - Uruchamianie komend w osobnych kartach. Nowa zakładka może być utworzona skrótem ctrl+shift+t. Żeby zmienić zakładką można wykorzystać skrót alt+X, gdzie X to numer terminala lub też ctrl+PageUp/PageDown. - Skorzystanie z terminala Terminator. - Skorzystanie z terminala tmux.

Zarządzanie pamiecią

Docker z czasem może zapełnić dysk twardy. Tworząc obrazy (np. na potrzeby tych zajęć) Docker przechowuje również wszystkie pliki i dane tymczasowe, które były używane podczas tworzenia obrazu. Ilość miejsca zajmowanego przez różne elementy Dockera można sprawdzić poleceniem:

docker system df

Aby oczyścić miejsce na dysku można skorzystać z polecenia:

docker system prune

UWAGA: Polecenie to usuwa wszystkie zatrzymane kontenery, sieci, woluminy i nieużywane obrazy. Należy zwrócić uwagę, żeby nie usunąć czegoś, co jest jeszcze potrzebne.

Bezpieczniej jest usunąć tylko nieużywane obrazy (dangling images). Są to takie obrazy, które nie są używane przez żaden kontener. Można je usunąć poleceniem:

docker image prune

Warto również zwrócić uwagę, że Docker przechowuje również pliki cache, niezbędne do szybkiego budowania obrazów. Można je usunąć poleceniem:

docker builder prune

Opcjonalnie można dodać flagę -a żeby usunąć wszystkie pliki cache, nie tylko niepowiązane z żadnym obrazem. UWAGA: Usunięcie plików cache spowoduje, że budowanie obrazów będzie trwało dłużej.

Zadania do samodzielnej realizacji

  1. Stwórz kontener ARM_01 korzystając z przygotowanych skryptów.
  2. Zatrzymaj i wystartuj kontener oraz podłącz do niego wiele terminali.
  3. Zainstaluj w kontenerze pakiet gedit:
apt update
apt install gedit
  1. Uruchom gedit w kontenerze i sprawdź, czy okienko wyświetla się prawidłowo.
  2. Zmodyfikuj skrypt tworzący kontener i przekaż do kontenera wybrany katalog systemowy. Jak sprawić, żeby możliwa była edycja na hostcie pliku, który został utworzony w dockerze?

Dodatek: Docker w VS Code

Praca z wykorzystaniem dockera może być nieco uciążliwa przez nieustanną konieczność poruszania się w terminalu. Korzystając z programu Visual Studio Code możemy jednak podłączyć się do kontenera i pracować na jego plikach tak jakby były to pliki na hostcie.

Instalacja VS Code i rozszerzeń

Na komputerach w laboratorium wszystko powinno być już zainstalowane.

Wszystkie kroki należy wykonać bez wykorzystania dockera.

Ze strony VS Code należy pobrać plik .deb i zainstalować go poleceniem

sudo apt install ./<file>.deb

VS Code można uruchomić z listy aplikacji lub poleceniem

code

Z listy rozszerzeń po lewej stronie (lub ctrl+shift+x) należy wyszukać Dev Containers(ms-vscode-remote.remote-containers) i je zainstalować.

Następnie, po kliknięciu przycisku w lewym dolnym rogu (nakładające się symbole “>” i “<”) można wybrać pozycję “Attach to Running Container” i wybrać uruchomiony kontener. Jeżeli kontener nie jest uruchomiony należy go uruchomić tak jak opisano powyżej.

Od tej pory można pisać kod, uruchamiać go i zapisywać w kontenerze korzystając z VS Code.


Autorzy: Kamil Młodzikowski, Michał Nowicki